package cn.xshi.oauth.client.timer;

import cn.hutool.core.collection.CollectionUtil;
import cn.xshi.common.base.BaseHttpSessionEntity;
import cn.xshi.common.util.RestTemplateUtil;
import cn.xshi.oauth.client.constant.Constant;
import cn.xshi.oauth.client.timer.task.CommandTokenTask;
import cn.xshi.oauth.client.util.HeartbeatAttributesUtil;
import cn.xshi.oauth.client.util.OauthAttributesUtil;
import cn.xshi.oauth.client.util.TokenAttributesUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ForkJoinPool;

/**
 * @Desc
 * @Author 邓纯杰
 * @CreateTime 2012-12-12 12:12:12
 */
@Slf4j
@Component
public class CommandToken {

    @Resource
    OauthAttributesUtil oauthAttributesUtil;

    @Resource
    TokenAttributesUtil tokenAttributesUtil;

    @Resource
    RestTemplateUtil restTemplateUtil;

    @Resource
    HeartbeatAttributesUtil heartbeatAttributesUtil;

    /**
     * 验证Token是否失效
     */
    @Scheduled(cron="*/30 * * * * *")
    public void execute() {
        try {
            if(heartbeatAttributesUtil.isConnected()){
                initForkJoinPool();
            }else{
                log.error("无法连接授权中心...");
            }
        }catch (Exception e){
            log.error("连接授权中心异常，异常信息：",e);
        }
    }

    /**
     * 筛选需要PULL的Token信息
     * @return
     */
    public Map<String,Integer> filterKeepAliveToken(){
        Map<String,BaseHttpSessionEntity> attributes = oauthAttributesUtil.getAttributes();
        if(CollectionUtil.isEmpty(attributes)){
            return null;
        }
        Map<String,Integer> map = new HashMap<>();
        Iterator<Map.Entry<String, BaseHttpSessionEntity>> entryIterator = attributes.entrySet().iterator();
        while (entryIterator.hasNext()) {
            Map.Entry<String, BaseHttpSessionEntity> e = entryIterator.next();
            map.put(e.getKey(),0);
        }
        return map;
    }

    /**
     *
     */
    public void initForkJoinPool(){
        long millis1 = System.currentTimeMillis();
        int size = Runtime.getRuntime().availableProcessors();//获取本系统的有效线程数，设置线程池为有效线程的两倍。
        ForkJoinPool forkJoinPool = new ForkJoinPool(size*2);
        try {
            Map<String,Integer> tokenMap = filterKeepAliveToken();
            if(CollectionUtil.isEmpty(tokenMap)){
                return;
            }
            CommandTokenTask initTask = new CommandTokenTask(tokenMap, Constant.PULL_TOKEN_GROUP_NUMBER,restTemplateUtil,oauthAttributesUtil,tokenAttributesUtil);
            //方法一 同步
            Integer result = forkJoinPool.invoke(initTask);
//                //线程阻塞，等待所有任务完成
//                forkJoinPool.awaitTermination(forkJoinTimeOut, TimeUnit.SECONDS);


//                //方法二 异步
//                ForkJoinTask forkJoinTask = forkJoinPool.submit(initTask);
//                result = new Integer(forkJoinTask.get());


//                //方法三 异步
//                Future<Integer> futureResult = forkJoinPool.submit(initTask);
//                result = futureResult.get();
            long millis2 =  System.currentTimeMillis();
            log.info("验证本地Token是否过期，耗时:"+(millis2-millis1)+"毫秒，共更新："+result+"条记录！");
        }catch (Exception e){
            if(null != forkJoinPool){
                forkJoinPool.shutdown();
            }
        }finally {
            if(null != forkJoinPool){
                forkJoinPool.shutdown();
            }
        }
    }
}
